/**
 *******************************************************************************
 * @FileName  : uart.c
 * @Author    : GaoQiu
 * @CreateDate: 2020-05-18
 * @Copyright : Copyright(C) GaoQiu
 *              All Rights Reserved.
 *******************************************************************************
 */
#include "uart.h"
#include "platform/platform.h"

/*! UART mode config define. */
#define UART_MODE_NORMAL 0
#define UART_MODE_DMA    1
#define UART_MODE        UART_MODE_DMA


/*! UART DMA mode rx buffer define. */
#if UART_MODE == UART_MODE_DMA
uint8_t rxBuf[64];//must 16Bytes align.
#endif

void UART_SetUp(void)
{
	/* Set UART/DMA clock. */
	RCC_EnablePeriphClk(RCC_UART | RCC_DMA);

	/* GPIO config. */
	GPIO_InitType_t GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;//RX
	GPIO_InitStruct.GPIO_Pull = GPIO_PullUp_Strong;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_In;
	GPIO_Init(GPIOB, &GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_1;//TX
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_Out;
	GPIO_Init(GPIOB, &GPIO_InitStruct);

	/* Set GPIO alternative function. */
	GPIO_SetAlternFunc(GPIOB, GPIO_Pin_0, GPIO_AF_UART);
	GPIO_SetAlternFunc(GPIOB, GPIO_Pin_1, GPIO_AF_UART);

	/* Configurate UART */
	UART_InitType_t UART_InitStruct;
	UART_InitStruct.SysClkFreq      = 48000000;
	UART_InitStruct.UART_BaudRate   = 115200;
	UART_InitStruct.UART_HwFlowCtrl = UART_HwFlowCtrl_None;
	UART_InitStruct.UART_Parity     = UART_Parity_No;
	UART_InitStruct.UART_StopBits   = UART_StopBits_1;
	UART_Init(&UART_InitStruct);

#if UART_MODE == UART_MODE_NORMAL
	/* UART Normal mode config. */
	UART_ITConfig(UART_IT_Rx, ENABLE);
	UART_ClearITFlagState(UART_IT_Flag_RxDone);
	IRQ_EnablePeriphIrq(IRQ_UART);
#else
	/* UART DMA mode config. */
	UART_DmaConfig(rxBuf, sizeof(rxBuf));
	UART_DmaITConfig(UART_DMA_IT_Rx, ENABLE);
	UART_DmaCmd(UART_DMA_Rx_Tx, ENABLE);

	/* Enabe UART peripheral interrupt. */
	IRQ_EnablePeriphIrq(IRQ_DMA);
#endif
}

void UART_Loop(void)
{
#if UART_MODE == UART_MODE_NORMAL
	uint8_t data[]={0xaa};
	UART_SendData(data, sizeof(data));
#else
	              /* data length | data   */
	uint8_t data[]={0x02,0,0,0,    0xAA,0xBB};
	UART_SendDataByDma(data);
#endif
	delay_ms(100);
}

void UART_IRQHandler(void)
{
	/* UART Normal Mode */
	if(UART_GetITFlagState(UART_IT_Flag_RxDone))
	{
		UART_ClearITFlagState(UART_IT_Flag_RxDone);

		UART_SendByte(UART_ReceiveByte());
	}

	/* UART DMA Mode */
	if(UART_GetDmaITFlagState(UART_DMA_IT_Flag_RxDone))
	{
		UART_ClearDmaITFlagState(UART_DMA_IT_Flag_RxDone);

		UART_SendDataByDma(rxBuf);
	}
	if(UART_GetDmaITFlagState(UART_DMA_IT_Flag_TxDone))
	{
		UART_ClearDmaITFlagState(UART_DMA_IT_Flag_TxDone);
	}
}
